// Copyright DustedPixels.com 2008. All rights reserved.

package com.dustedpixels.jasmin.unit.tools;

import java.util.ArrayList;

/**
 * @author micapolos@gmail.com (Michal Pociecha-Los)
 */
public final class Oscilloscope {
  private final Pin[] pins;
  private final ArrayList<ArrayList<Sample>> samples;
  private final int maxPinNameLength;
  
  public Oscilloscope(Pin... pins) {
    this.pins = pins;
    
    int maxPinNameLength = 0;
    this.samples = new ArrayList<ArrayList<Sample>>();
    for (int i = 0; i < pins.length; i++) {
      this.samples.add(new ArrayList<Sample>());
      maxPinNameLength = Math.max(maxPinNameLength, pins[i].pinName.length());
    }
    
    this.maxPinNameLength = maxPinNameLength;
  }
  
  public void sample() {
    for (int i = 0; i < pins.length; i++) {
      Pin pin = pins[i];
      samples.get(i).add(pin.sample());
    }
  }
  
  public void print(int barPinIndex) {
    Pin barPin = pins[barPinIndex];
    boolean lastBarPinSample = false;
    
    for (int i = 0; i < pins.length; i++) {
      Pin pin = pins[i];
      
      for (int n = 0; n < maxPinNameLength + 2; n++) {
        System.out.print(" ");
      }
      for (int n = 0; n < samples.get(i).size(); n++) {
        Sample sample = samples.get(i).get(n);

        // Update bar
        boolean barPinSample = samples.get(barPinIndex).get(n) == Sample.HIGH;
        if (!lastBarPinSample && barPinSample) {
          System.out.print("|"); 
        }
        lastBarPinSample = barPinSample;
        
        if (sample == Sample.HIGH) {
          System.out.print("_");
        } else {
          System.out.print(" ");
        }
      }
      System.out.println();

      for (int n = 0; n < maxPinNameLength - pin.pinName.length(); n++) {
        System.out.print(" ");
      }
      System.out.print(pin.pinName + ": ");
      for (int n = 0; n < samples.get(i).size(); n++) {
        Sample sample = samples.get(i).get(n);
        
        // Update bar
        boolean barPinSample = samples.get(barPinIndex).get(n) == Sample.HIGH;
        if (!lastBarPinSample && barPinSample) {
          System.out.print("|"); 
        }
        lastBarPinSample = barPinSample;

        if (sample == Sample.HI_Z) {
          System.out.print("-");
        } else if (sample == Sample.LOW) {
          System.out.print("_");
        } else if (sample.type == Sample.Type.MIXED){
          System.out.print(Integer.toHexString(sample.mixedValue & 0x0F));
        } else {
          System.out.print(" ");
        }
      }
      System.out.println();
    }
  }
}
